package controllers

import (
	"fmt"
	"ginstudydemo.com/main/config"
	"ginstudydemo.com/main/models"
	"ginstudydemo.com/main/service"
	"github.com/gin-gonic/gin"
	"github.com/tencentyun/cos-go-sdk-v5"
	"math/rand"
	"net/http"
	"net/url"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

type IFileController interface {
	UploadFile()
}

type FileController struct{}

func NewFileController() *FileController {
	return &FileController{}
}

// generateFileNameWithPath 生成带子目录的文件路径和文件名
func generateFileNameWithPath(userID int, originalFilename string) string {
	now := time.Now()
	randomNum := rand.Intn(10000)
	extension := filepath.Ext(originalFilename) // 获取文件的后缀

	// 设置子目录路径，例如 "uploads/2024/11"
	subDir := fmt.Sprintf("gin_test/%d/%02d", now.Year(), now.Month())

	// 将文件名和目录组合
	return fmt.Sprintf("%s/%d_%02d_%02d_%02d_%02d_%02d_%04d_%d%s",
		subDir,
		now.Year(), now.Month(), now.Day(),
		now.Hour(), now.Minute(), now.Second(),
		randomNum, userID, extension)
}

// getFileType 根据文件扩展名获取文件类型
func getFileType(extension string) int {
	extension = strings.ToLower(extension)
	switch extension {
	case ".jpg", ".jpeg", ".png", ".gif", ".bmp":
		return 1 // 图片
	case ".mp3", ".wav", ".flac", ".aac":
		return 2 // 音频
	case ".mp4", ".avi", ".mov", ".mkv":
		return 3 // 视频
	default:
		return 4 // 除音视频图片以外文件类型
	}
}

// UploadFile 上传文件
func (f FileController) UploadFile(c *gin.Context) {
	// 获取文件头
	fileHeader, formErr := c.FormFile("file")
	if formErr != nil {
		service.ReturnErr(c, "9999", "error:File upload failed:"+formErr.Error())
		c.Abort()
		return
	}

	// 打开文件内容
	file, fOpenErr := fileHeader.Open()
	if fOpenErr != nil {
		service.ReturnErr(c, "9999", "error:Unable to open file:"+fOpenErr.Error())
		c.Abort()
		return
	}
	defer file.Close()

	//根据token获取用户信息
	claims, exists := c.Get("claims")
	if !exists {
		service.ReturnErr(c, "5005", "无法获取token信息")
		return
	}

	// 现在可以使用 claims 执行相关操作
	myClaims := claims.(*service.MyClaims)
	fmt.Println("------------")
	fmt.Println(myClaims.UserInfo.UserID)

	// 示例用户 ID（实际项目中获取实际用户 ID）
	userID := myClaims.UserInfo.UserID

	// 获取文件信息
	mimeType := fileHeader.Header.Get("Content-Type")
	extension := filepath.Ext(fileHeader.Filename)
	fileSize := fileHeader.Size
	fileType := getFileType(extension)

	// 生成带子目录的文件名
	newFilePath := generateFileNameWithPath(int(userID), fileHeader.Filename)

	// 设置 COS Bucket URL
	u, _ := url.Parse(config.COS_Bucket_URL)
	b := &cos.BaseURL{BucketURL: u}

	// 初始化 COS 客户端
	client := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  config.COS_SecretId,
			SecretKey: config.COS_SecretKey,
		},
	})

	// 上传文件到 COS
	fileURL, upErr := service.NewFileService().UploadFile(client, newFilePath, file)
	if upErr != nil {

		service.ReturnErr(c, "9999", "error:Failed to upload file to COS:"+upErr.Error())
		c.Abort()
		return
	}

	// 上传文件信息存储到数据库
	fileData := models.SysFileMateAddData{
		FilePathCos:   fileURL,
		MineType:      mimeType,
		FileType:      strconv.Itoa(fileType), // 例如：1 表示图片
		FileUse:       "gin_test",
		FileExtension: extension,
		FileSize:      strconv.FormatInt(fileSize, 10),
		UploadTime:    time.Now(),
	}

	insertData, modelErr := models.AddFileMate(fileData)
	if modelErr != nil {
		service.ReturnErr(c, "9999", "error:inserting file data#"+modelErr.Error())
		c.Abort()
		return
	}

	service.ReturnSuccess[models.SysFileMateAddData](c, "2000", "ok", insertData)

}
